#include "Analysis.h" 

using namespace std;

CAnalysis::CAnalysis()
{
}

CAnalysis::~CAnalysis()
{
}

int CAnalysis::GetPosType(int x,int y,int maxX,int maxY)
{
	int posType=0;

	if (x>=maxX)
	{
		posType=1;
		if (y>=maxY) posType=2;
		if (y<0) posType=8;
	}
	if ((x<maxX) && (x>=0))
	{
		posType=0;
		if (y>=maxY) posType=3;
		if (y<0) posType=7;
	}
	if (x<0)
	{
		posType=5;
		if (y>=maxY) posType=4;
		if (y<0) posType=6;
	}
	
	return posType;
}

double CAnalysis::GetMatAverage(int order, CHeader* matList, int type)
{
	int ii;
	double average=0;
	
	for (ii=order-1;ii>0;ii--)
		matList[ii-1].m_nodePixelCount[type]
		+=matList[ii].m_nodePixelCount[type];

	for (ii=order-1;ii>=0;ii--)
		average+=(double)(matList[ii].m_nodePixelCount[type])
			/matList[ii].m_nodeCount;
	
	average=average/order;
	
	return average;
}

double CAnalysis::GetFreqAverage(int order, CHeader* matList, int type)
{
	int ii;
	double average=0;
	
	
	for (ii=order-1;ii>0;ii--)
		matList[ii-1].m_nodePixelCount[type]
		+=matList[ii].m_nodePixelCount[type];

	for (ii=order-1;ii>=0;ii--)
		average+=(double)matList[ii].m_nodePixelCount[type];
	
	average=average/order;
	
	return average;
}

DENSITYMAP CAnalysis::CalcDensity(CMap* Map, int indexType, CMatrix* Matrix, int matType, int outMapType)
{
	int posX, posY, posType;
	int orderLoop;
	int matX, matY;
	int grID, grNum;
	int tempID;
	int mapHeight, mapWidth;
	int orderCount;
	CNode* tempNode=NULL;
	bool grList[9][MAXGRNUM];
	
	INDEXMAP indexMap=NULL;
	INDEXMAP matMap=NULL;
		
	indexMap=Map->IndexMapType(indexType, NULL);
	
	matMap=Matrix->MatrixType(matType, NULL);
	
	CHeader* matList=Matrix->MakeMatrixList(matMap);

	DENSITYMAP totalMap=Map->MakeNULLDensityMap();
	DENSITYMAP singleMap=NULL;
	DENSITYMAP aroundMap=NULL;
	DENSITYMAP freqMap=NULL;
	
	if (outMapType==DENSITY)
	{
		singleMap=Map->MakeNULLDensityMap();
		aroundMap=Map->MakeNULLDensityMap();
		freqMap=Map->MakeNULLDensityMap();
	}
	
	//indexMap=Map->index;
	//matList=matList;
//	cout<<"Start density analysis..."<<endl;
	
	mapHeight=Map->GetHeight();
	mapWidth=Map->GetWidth();
	orderCount=Matrix->GetNumOrder();

	for (posY=0;posY<mapHeight;posY++)
		for (posX=0;posX<mapWidth;posX++)
		{
				grID=indexMap[posX][posY];
				
				for (orderLoop=0;orderLoop<orderCount;orderLoop++)
				{
					matList[orderLoop].m_nodePixelCount[SINGLE]=0;
					matList[orderLoop].m_nodePixelCount[AROUND]=0;
					matList[orderLoop].m_nodePixelCount[TOTAL]=0;
					matList[orderLoop].m_nodePixelCount[FREQUENCY]=0;
				}
			
				for (grNum=0;grNum<MAXGRNUM;grNum++)
					for (posType=0;posType<9;posType++)
						grList[posType][grNum]=false;

//				for (orderLoop=0;orderLoop<orderCount;orderLoop++)
				for (orderLoop=orderCount-1;orderLoop>=0;orderLoop--)
				{
					tempNode=matList[orderLoop].m_node;
					
					while (tempNode!=NULL)
					{
						matX=(tempNode->m_x)+posX;
						matY=(tempNode->m_y)+posY;
						posType=GetPosType(matX,matY,mapWidth,mapHeight);

						matX=matX%(mapWidth);
						if (matX<0) matX+=(mapWidth);
						
						matY=matY%(mapHeight);
						if (matY<0) matY+=(mapHeight);
							
						tempID=indexMap[matX][matY];

						if (tempID!=NODATA) 
						{
							matList[orderLoop].m_nodePixelCount[TOTAL]++; 
							if (tempID==grID)
								matList[orderLoop].m_nodePixelCount[SINGLE]++;
							else 
								matList[orderLoop].m_nodePixelCount[AROUND]++;

							if (grList[posType][tempID]==false)
							{
								grList[posType][tempID]=true;
								matList[orderLoop].m_nodePixelCount[FREQUENCY]++;
							}

						}
						tempNode=tempNode->m_nextNode;
					} //while
				} //for orderLoop
			
				totalMap[posX][posY]=GetMatAverage(orderCount, matList, TOTAL);
				if (outMapType==DENSITY)
				{
					singleMap[posX][posY]=GetMatAverage(orderCount, matList, SINGLE);
					aroundMap[posX][posY]=GetMatAverage(orderCount, matList, AROUND);
					freqMap[posX][posY]=GetFreqAverage(orderCount, matList, FREQUENCY);
				}
			}//for posX, posY
	
	Matrix->DeleteMatrixList(matList);
			
	Map->m_densityMap[outMapType]=totalMap;
	if (outMapType==DENSITY)
	{
		Map->m_densityMap[SIZE]=singleMap;
		Map->m_densityMap[CLUSTER]=aroundMap;
		Map->m_densityMap[FREQ]=freqMap;
	}

	return totalMap;
			
}

/*
void CAnalysis::FreqAnalysis(CMap* Map, CMatrix* Matrix)
{
	int grNum, totalGrNum;
	int posX, posY, posType;
	int orderLoop;
	int matX, matY;
	int grID;
	int tempID;
	int mapHeight, mapWidth;
	int orderCount;
	CNode* tempNode=NULL;

	bool grList[9][MAXGRNUM];
	bool totalGrList[9][MAXGRNUM];

	cout<<"Start frequency analysis..."<<endl;
	
	mapHeight=Map->m_height;
	mapWidth=Map->m_width;
	orderCount=Matrix->m_order;

	for (totalGrNum=0;totalGrNum<MAXGRNUM;totalGrNum++)
		for (posType=0;posType<9;posType++)
			totalGrList[posType][totalGrNum]=false;
	totalGrNum=0;
	
	for (posY=0;posY<mapHeight;posY++)
		for (posX=0;posX<mapWidth;posX++)
		{
				grID=Map->index[posX][posY];
				
				for (orderLoop=0;orderLoop<orderCount;orderLoop++)
				{
					Matrix->m_header[orderLoop].m_nodePixelCount[3]=0;
				}
				
				for (grNum=0;grNum<MAXGRNUM;grNum++)
					for (posType=0;posType<9;posType++)
						grList[posType][grNum]=false;
				
//				for (orderLoop=0;orderLoop<orderCount;orderLoop++)
				for (orderLoop=orderCount-1;orderLoop>=0;orderLoop--) //占쏙옙占싸울옙占쏙옙占쏙옙占쏙옙 占쏙옙占�
				{
					tempNode=Matrix->m_header[orderLoop].m_node;
					
					while (tempNode!=NULL)
					{
						matX=(tempNode->m_x)+posX;
						matY=(tempNode->m_y)+posY;
						posType=GetPosType(matX,matY,mapWidth,mapHeight);

						if (posType!=0)
						{
							matX=matX%(mapWidth);
							if (matX<0) matX+=(mapWidth);
							
							matY=matY%(mapHeight);
							if (matY<0) matY+=(mapHeight);
						}
							
						tempID=Map->index[matX][matY];

						if (tempID!=NODATA) 
						{
							if (grList[posType][tempID]==false)
							{
								grList[posType][tempID]=true;
								Matrix->m_header[orderLoop].m_nodePixelCount[3]++;
							}
							if (totalGrList[posType][tempID]==false)
							{
								totalGrList[posType][tempID]=true;
								totalGrNum++;
							}
						}
						tempNode=tempNode->m_nextNode;
					} //while
				} //for orderLoop
			
				Map->freq[posX][posY]=GetMatAverage(Matrix, 3);
			}//for posX, posY
	cout<<"total Grain Num: "<<totalGrNum<<endl;
	cout<<"Analysis is done."<<endl;

}
*/

void CAnalysis::PrintStatistics(CMap* Map, CMatrix* Matrix)
{
	int ordCount; 
	int* orderList;
	char mapName[256];
	
	strcpy(mapName,Map->GetMapName());
	orderList=Matrix->GetOrderList();
	
	strcat(mapName,"_statistics.txt");
	
	ofstream f1;
	
	f1.open(mapName);
	
	f1<<"Map Height:"<<"\t"<<Map->GetHeight()<<endl;
	f1<<"Map Width:"<<"\t"<<Map->GetWidth()<<endl;
	f1<<"Fraction:"<<"\t"<<Map->Fraction()<<endl;
	f1<<"Number of grains:"<<"\t"<<Map->GetGrainAmount()<<endl;
	f1<<"Matrix order:"<<"\t"<<Matrix->GetNumOrder()<<"\torders"<<endl;
	
	f1<<"Matrix radius :"<<endl;
	ordCount=0;
	while (orderList[ordCount]>0)
	{
		f1<<orderList[ordCount]<<"\t";
		ordCount++;
	}
	f1<<endl;
	
	f1<<"Matrix type :"<<"\t"<<"all"<<endl<<endl;
	
	f1<<"Average density:"<<"\t"<<Map->Average(DENSITY)<<endl;
	f1<<"Max. density:"<<"\t"<<Map->FindMaxDensity(DENSITY)<<endl;
	f1<<"Min. density:"<<"\t"<<Map->FindMinDensity(DENSITY)<<endl;
	f1<<endl;

	f1<<"Standard Deviation:"<<"\t"<<Map->StandardDev(DENSITY)<<endl;
	if (Map->m_densityMap[MAX]!=NULL)
	{
		f1<<"Clustering factor:"<<"\t"<<(Map->StandardDev(DENSITY)/Map->StandardDev(MAX))<<"\t";
		f1<<endl;
	}
	else f1<<endl;
	if ((Map->m_densityMap[HOR]!=NULL)&&(Map->m_densityMap[VER]!=NULL))
	{
		f1<<"H/V ratio:"<<"\t"
			<<(Map->StandardDev(HOR))/(Map->StandardDev(HOR))<<"\t";
		f1<<endl;
	}
	else f1<<endl;
//	f1<<"Positve SD:"<<"\t"<<PositiveStandardDev(mapType)<<endl;
//	f1<<"Negative SD:"<<"\t"<<NegativeStandardDev(mapType)<<endl;
//	f1<<endl;
//	f1<<endl;
	f1<<endl;
	f1<<endl;
	f1<<endl;
	f1<<"Other values"<<endl;
	f1<<" Input file name:"<<"\t"<<Map->GetFileName()<<endl;
	f1<<" Max. matrix size:"<<"\t"<<orderList[0]<<endl;
	f1<<" Min. matrix size:"<<"\t"<<orderList[ordCount-1]<<endl;
	f1<<" Matrix size interval:"<<"\t"<<(orderList[0]-orderList[1])<<endl;
	f1<<" The number of matrix:"<<"\t"<<ordCount<<endl;
	f1<<" Total pixels:"<<"\t"<<Map->GetHeight()*Map->GetWidth()<<endl;
	f1<<" Phase pixels:"<<"\t"<<Map->GetGrainPixels()<<endl;
	f1<<" Max circle pixels:"<<"\t"<<Map->GetMaxPixels()<<endl;
	
	#ifdef DEBUG
	
	f1<<" Null averge:"<<"\t"<<Map->NullAverage(DENSITY)<<endl;
	f1<<" Pahse averge:"<<"\t"<<Map->PhaseAverage(DENSITY)<<endl;
	f1<<" Positive SD:"<<"\t"<<Map->PositiveStandardDev(DENSITY)<<endl;
	f1<<" Negative SD:"<<"\t"<<Map->NegativeStandardDev(DENSITY)<<endl;
	if (Map->m_densityMap[MAX]!=NULL)
		f1<<" MAX SD:"<<"\t"<<Map->StandardDev(MAX)<<endl;
	if (Map->m_densityMap[HOR]!=NULL)
		f1<<" HOR SD:"<<"\t"<<Map->StandardDev(HOR)<<endl;
	if (Map->m_densityMap[VER]!=NULL)
		f1<<" VER SD:"<<"\t"<<Map->StandardDev(VER)<<endl;
	#endif
	
	f1<<endl;
	
	f1.close();
}


